<?php
namespace PsiFramework\Classes\Util\Parameters\Object;

import("Classes.Util.Database.Query.SqlType");
import("Classes.Util.Manager.ObjectManager");

use \PsiFramework\Classes\Util\Database\Query\SqlType;
use \PsiFramework\Classes\Util\Manager\ObjectManager;

/**
 * PsiFramework
 * Php Simple Framework
 *
 * @author Rémi San
 * @version beta
 */

/**
 * The AttributeParameters class is the class to manage
 * object parameters attributes
 *
 * @package Util.Parameters.Object
 */
class AttributeParameters
{

    public /*string*/ $name = null ;
    public /*string*/ $column = null ;
    public /*string*/ $foreignColumn = null ;
    public /*string*/ $type = null ;
    public /*string*/ $sqlType = null ;
    public /*string*/ $length = null ;
    public /*string*/ $sequence = null ;
    public /*bool*/   $primaryKey = false ;
    public /*bool*/   $unique = false ;
    public /*bool*/   $canBeNull = false ;
    public /*string*/ $getter = null ;
    public /*string*/ $setter = null ;
    public /*bool*/   $isArray = false ;
    public /*bool*/   $display = true ;
    public /*bool*/  $lazy = null ;

    public function __construct(/*array*/ $atts = null)
    {

        if ($atts != null) {
            $this->name
                = (isset($atts['name'])) ?
                    $atts['name'] : null ;
            $this->column
                = (isset($atts['column'])) ?
                    $atts['column'] : null ;
            $this->foreignColumn
                = (isset($atts['foreignColumn'])) ?
                    $atts['foreignColumn'] : null ;
            $this->length
                = (isset($atts['length'])) ?
                    $atts['length'] : null ;
            $this->sequence
                = (isset($atts['sequence'])) ?
                    $atts['sequence'] : null ;
            $this->canBeNull
                = (isset($atts['nullable'])) ?
                    (($atts['nullable']=='false') ? false : true ) : true ;
            $this->primaryKey
                = (isset($atts['primaryKey'])) ?
                    (($atts['primaryKey']=='true') ? true : false ) : false ;
            $this->unique
                = (isset($atts['unique'])) ?
                    (($atts['unique']=='true') ? true : false ) : false ;
            $this->display
                = (isset($atts['display'])) ?
                    (($atts['display']=='false') ? false : true ) : true ;

            $type = (isset($atts['type'])) ? $atts['type'] : null ;
            if (endsWith($type, '[]')) {
                $this->type = substr($type, 0, strlen($type)-2);
                $this->isArray = true ;
            } else {
                $this->type = $type ;
            }

            $this->sqlType = null ;
            if (isset($atts['sqlType'])) {
                $this->sqlType = $atts['sqlType'] ;
            }
            if (is_null($this->sqlType) && !is_null($this->type)) {
                $this->getSqlType(!is_null($this->sequence)&&$this->primaryKey);
            }

            $upperName = ($this->name != null) ? ucfirst($this->name) : null ;
            if (!is_null($upperName)) {
                $chars = array(
                    '-',
                    '+',
                    '.',
                    '/',
                    ' ',
                    '<',
                    '>',
                    ',',
                    '!',
                    ';',
                    ':'
                );
                foreach ($chars as $char) {
                    $upperName = str_replace('-', '', $upperName);
                }

                if ($this->type == 'bool' || $this->type == 'boolean') {
                    $this->getter = "is" . $upperName ;
                } else {
                    $this->getter = "get" . $upperName ;
                }
                $this->setter = "set" . $upperName ;
            } else {
                $this->getter = null ;
                $this->setter = null ;
            }

            if (isset($atts['lazy'])) {
                if ($atts['lazy']=='true') {
                    $this->lazy = true ;
                } else {
                    $this->lazy = false ;
                }
            } else {
                if ($this->isArray) {
                    $this->lazy = true ; //if array, default lazy
                } else {
                    $this->lazy = false ; //if one object, default eager
                }
            }
        }
    }

    public function isPrimitive()
    {
        return ObjectManager::getInstance()->isPrimitive($this->type);
    }

    public function isPrimitiveObject()
    {
        return ObjectManager::getInstance()->isPrimitiveObject($this->type);
    }

    protected function getSqlType(/*boolean*/ $pk=false)
    {

        if ($this->isPrimitiveObject()) {
            $type = ObjectManager::getInstance()->importPrimitiveObject($this->type);
            $this->sqlType = call_user_func(array($type, 'getSqlType'));
            return;
        }

        $type = mb_strtoupper($this->type, 'utf-8');
        switch($type) {
        case 'STRING' :
            $this->sqlType = SqlType::$varchar ;
            break;
        case 'TEXT' :
            $this->sqlType = SqlType::$text ;
            break;
        case 'INT' :
        case 'INTEGER' :
            if ($pk) {
                $this->sqlType = SqlType::$serial ;
            } else {
                $this->sqlType = SqlType::$integer ;
            }
            break;
        case 'LONG' :
            $this->sqlType = SqlType::$long ;
            break;
        case 'DOUBLE' :
            $this->sqlType = SqlType::$double ;
            break;
        case 'FLOAT' :
            $this->sqlType = SqlType::$float ;
            break;
        case 'BOOL' :
        case 'BOOLEAN' :
            $this->sqlType = SqlType::$boolean ;
            break;
        }
    }

}
